import {ElNotification  as message} from 'element-plus'
// import {getWsBaseURL} from "/@/utils/baseUrl"; //获取ws接口的方法,可自行换掉
const { VITE_API_URL } = import.meta.env.VITE_API_URL;

import {SocketImpl} from './websocket'
import {getToken} from "@/utils/auth";

const websocket: SocketImpl = {
  websocket: null,
  // connectURL: getWsBaseURL(),
  connectURL: VITE_API_URL,
  // 开启标识
  socket_open: false,
  // 心跳timer
  hearbeat_timer: null,
  // 心跳发送频率
  hearbeat_interval: 2 * 1000,
  // 是否自动重连
  is_reonnect: true,
  // 重连次数
  reconnect_count: 3,
  // 已发起重连次数
  reconnect_current: 1,
  // 重连timer
  reconnect_timer: null,
  // 重连频率
  reconnect_interval: 5 * 1000,
  init: (receiveMessage: Function | null) => {
    if (!('WebSocket' in window)) {
      message.warning('浏览器不支持WebSocket')
      return null
    }
    const token = getToken();
    if(!token){
      message.warning('websocket认证失败')
      return null
    }
    // const wsUrl = `${VITE_API_URL}/ws/${token}/`
    const wsUrl = `ws://121.40.165.18:8800`
    websocket.websocket = new WebSocket(wsUrl)
    websocket.websocket.onmessage = (e: any) => {
      if (receiveMessage) {
        receiveMessage(e)
      }
    }
    websocket.websocket.onclose = (e: any) => {
      websocket.socket_open = false
      // 需要重新连接
      if (websocket.is_reonnect) {
        websocket.reconnect_timer = setTimeout(() => {
          // 超过重连次数
          if (websocket.reconnect_current > websocket.reconnect_count) {
            clearTimeout(websocket.reconnect_timer)
            websocket.is_reonnect = false
            return
          }
          // 记录重连次数
          websocket.reconnect_current++
          websocket.reconnect()
        }, websocket.reconnect_interval)
      }
    }
    // 连接成功
    websocket.websocket.onopen = function () {
      websocket.socket_open = true
      websocket.is_reonnect = true
      // 开启心跳
      websocket.heartbeat()
    }
    // 连接发生错误
    websocket.websocket.onerror = function () { }
  },
  heartbeat: () => {
    websocket.hearbeat_timer && clearInterval(websocket.hearbeat_timer)

    websocket.hearbeat_timer = setInterval(() => {
      let data = {
        token: getToken()
      }
      websocket.send(data)
    }, websocket.hearbeat_interval)
  },
  send: (data:string, callback = null) => {
    // 开启状态直接发送
    if (websocket.websocket.readyState === websocket.websocket.OPEN) {
      websocket.websocket.send(JSON.stringify(data))
      // @ts-ignore
      callback && callback()
    } else {
      clearInterval(websocket.hearbeat_timer)
      message({
        type: 'warning',
        message: 'socket链接已断开',
        duration: 1000,
      })
    }
  },
  close: () => {
    websocket.is_reonnect = false
    websocket.websocket.close()
    websocket.websocket = null;
  },
  /**
   * 重新连接
   */
  reconnect: () => {
    if (websocket.websocket && !websocket.is_reonnect) {
      websocket.close()
    }
    websocket.init(null)
  },
}

// 只允许在内部实例化
export class Socket {
  private constructor() { }
  private websocket: WebSocket = null
  // 开启标识
  public socket_open= false
  // 心跳timer
  private hearbeat_timer : NodeJS.Timer = null
  // 心跳发送频率
  private hearbeat_interval = 120 * 1000
  // 是否自动重连
  private is_reonnect = true
  // 重连次数
  private reconnect_count = 3
  // 已发起重连次数
  private reconnect_current = 1
  // 重连timer
  private reconnect_timer: NodeJS.Timer =  null
  // 重连频率
  private reconnect_interval= 5 * 1000
  // 是否实例的标志
  private static instance: Socket = null
  // 单例模式
  static getInstance () {
    // 判断系统是否已经有单例了
    if (Socket.instance === null) {
      Socket.instance = new Socket()
    }
    return Socket.instance
  }
  init(receiveMessage: Function | null) {
    if (!('WebSocket' in window)) {
      message.warning('浏览器不支持WebSocket')
      return null
    }
    const token = getToken();
    if(!token){
      message.warning('websocket认证失败')
      return null
    }
    // const wsUrl = `${VITE_API_URL}/ws/${token}/`
    const wsUrl = `ws://121.40.165.18:8800`
    this.websocket = new WebSocket(wsUrl)
    this.websocket.onmessage = (e: any) => {
      if (receiveMessage) {
        receiveMessage(e)
      }
    }
    this.websocket.onclose = (e: any) => {
      this.socket_open = false
      // 需要重新连接
      if (this.is_reonnect) {
        this.reconnect_timer = setTimeout(() => {
          // 超过重连次数
          if (this.reconnect_current > this.reconnect_count) {
            clearTimeout(this.reconnect_timer)
            this.is_reonnect = false
            return
          }
          // 记录重连次数
          this.reconnect_current++
          this.reconnect()
        }, this.reconnect_interval)
      }
    }
    // 连接成功
    this.websocket.onopen = () => {
      this.socket_open = true
      this.is_reonnect = true
      // 开启心跳
      this.heartbeat()
    }
    // 连接发生错误
    this.websocket.onerror = function () { }
  }
  heartbeat = () => {
    this.hearbeat_timer && clearInterval(this.hearbeat_timer)
    const me = this
    this.hearbeat_timer = setInterval(() => {
      let data = {
        token: getToken()
      }
      me.send(JSON.stringify(data.token))
    }, this.hearbeat_interval)
  }
  send = (data:string, callback = null) => {
    // 开启状态直接发送
    if (this.websocket.readyState === this.websocket.OPEN) {
      this.websocket.send(JSON.stringify(data))
      // @ts-ignore
      callback && callback()
    } else {
      clearInterval(this.hearbeat_timer)
      message({
        type: 'warning',
        message: 'socket链接已断开',
        duration: 1000,
      })
    }
  }
  close = () => {
    this.is_reonnect = false
    this.websocket.close()
    this.websocket = null;
  }
  // 重新连接
  reconnect = () => {
    if (websocket.websocket && !websocket.is_reonnect) {
      websocket.close()
    }
    websocket.init(null)
  }
}
export default websocket;
